<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>使用 Canvas 模拟 Plotly 绘制柱状图</title>
    <style>
        canvas {
            border: 1px solid #ccc;
        }
        #tooltip {
            position: absolute;
            background-color: rgba(0, 0, 0, 0.8);
            color: white;
            padding: 5px;
            
            border-radius: 3px;
            display: none;
        }
        
    </style>
</head>
<body>
    <canvas id="barChart" width="800" height="400"></canvas>
    <div id="tooltip"></div>
    <script>
        // 柱状图数据
        const data = [4, 8, 15, 16, 23, 42];
        const canvas = document.getElementById('barChart');
        const ctx = canvas.getContext('2d');
        const tooltip = document.getElementById('tooltip');

        // 计算柱子的宽度和间距
        const barWidth = 50;
        const barSpacing = 20;
        const startX = 50;
        const startY = canvas.height - 50;

        // 绘制坐标轴
        ctx.beginPath();
        ctx.moveTo(startX, startY);
        ctx.lineTo(startX, 50); // Y 轴
        ctx.lineTo(canvas.width - 50, startY); // X 轴
        ctx.stroke();

        // 绘制柱子
        const bars = [];
        data.forEach((value, index) => {
            const x = startX + index * (barWidth + barSpacing);
            const barHeight = value * 5; // 简单缩放数据以适应画布

            ctx.fillStyle = 'blue';
            ctx.fillRect(x, startY - barHeight, barWidth, barHeight);

            // 绘制柱子上方的数值标签
            ctx.fillStyle = 'black';
            ctx.font = '12px Arial';
            ctx.fillText(value, x + barWidth / 2 - 5, startY - barHeight - 5);

            bars.push({
                x,
                y: startY - barHeight,
                width: barWidth,
                height: barHeight,
                value
            });
        });

        // 监听鼠标移动事件
        canvas.addEventListener('mousemove', (e) => {
            const rect = canvas.getBoundingClientRect();
            const mouseX = e.clientX - rect.left;
            const mouseY = e.clientY - rect.top;

            let isHovering = false;
            bars.forEach((bar) => {
                if (
                    mouseX >= bar.x &&
                    mouseX <= bar.x + bar.width &&
                    mouseY >= bar.y &&
                    mouseY <= bar.y + bar.height
                ) {
                    isHovering = true;
                    tooltip.style.display = 'block';
                    tooltip.style.left = `${e.clientX + 10}px`;
                    tooltip.style.top = `${e.clientY}px`;
                    tooltip.textContent = `数值: ${bar.value}`;
                }
            });

            if (!isHovering) {
                tooltip.style.display = 'none';
            }
        });

        // 监听鼠标移出事件
        canvas.addEventListener('mouseout', () => {
            tooltip.style.display = 'none';
        });
    </script>
</body>
</html>